import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
import java.util.LinkedList;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;

/**
 * 
 * NewParserCallBack extends from the HTMLEditorKit.ParserCallback
 * rewrite the handleStartTag, handleEndTag, handleText
 * @author vihuynh, k7ho
 * 
 */
public class NewParserCallBack extends HTMLEditorKit.ParserCallback {
	private URL base; // storing which HTML we are in
	private Hashtable<String, Hashtable<String, Integer>> bigTbl;
	// key = keyword, value = hashtable<URL, hits count>
	private LinkedList<String> hrefList; // hrefList
	private LinkedList<String> anchorWords; //
	private Hashtable<String, LinkedList<String>> anchorList;

	int wordCount = 0; // # of read in lines
	boolean Atag = false;

	public NewParserCallBack(URL inURL,
			Hashtable<String, Hashtable<String, Integer>> inTbl,
			Hashtable<String, LinkedList<String>> smallTbl) {
		// initialize variables
		this.base = inURL;

		// System.err.println("base . url " + base.toString());
		this.bigTbl = inTbl;
		this.hrefList = new LinkedList<String>();
		this.anchorWords = new LinkedList<String>();
		this.anchorList = smallTbl;
	}

	/**
	 * handle the tag.A and check if the link is valid, if valid add to the list
	 * and turn the Atag flag true.  
	 * @see javax.swing.text.html.HTMLEditorKit.ParserCallback#handleStartTag(javax.swing.text.html.HTML.Tag, javax.swing.text.MutableAttributeSet, int)
	 */
	@SuppressWarnings("unused")
	@Override
	public void handleStartTag(HTML.Tag tag, MutableAttributeSet attr, int pos) {
		String aryTag = "<" + tag;
		if (tag == HTML.Tag.A) {
			String link = (String) attr.getAttribute(HTML.Attribute.HREF);
			Atag = false;
			if (link != null) {
				try {
					// link is absolute
					URL url = new URL(link);
					Atag = true;
					anchorWords.clear();
					hrefList.add(link);

				} catch (MalformedURLException mURL) {
					// link is not absolute

					try {
						
						String absLink = "";
						if (base.toString().endsWith("/")) {
							// base is absolute
							absLink = base.toString() + link;
						}
						else {
							// String absLink = base.toString() + link;
							absLink = base.toString();
							if (!link.startsWith("/")) {
								absLink = absLink.substring(0, absLink
										.lastIndexOf("/") + 1);
							}
							absLink = absLink + link;

						}
						// absLink = base.toString() + link;
						URL url = new URL(absLink);
						
						Atag = true;
						anchorWords.clear();
						hrefList.add(absLink);

					} catch (MalformedURLException e) {

						//System.err.println("Not vaild link > " + link);
					}

				}
			}

		}	
		aryTag += ">";
	}

	
	/**
	 * handle the a tag anchor words 
	 * add the linked list word to the anchor word hashtable and used it later 
	 * in index.java
	 * @see javax.swing.text.html.HTMLEditorKit.ParserCallback#handleEndTag(javax.swing.text.html.HTML.Tag, int)
	 */
	@Override
	public void handleEndTag(HTML.Tag t, int pos) {	

		if (t == HTML.Tag.A) {
			Atag = false;
			LinkedList<String> temp = new LinkedList<String>();
			temp.addAll(anchorWords);
			anchorList.put(hrefList.getLast(), temp);
		}
	}

	
	/**
	 * handle the text in the body of the html
	 * add the string to the bigHashtable 
	 * @see javax.swing.text.html.HTMLEditorKit.ParserCallback#handleText(char[], int)
	 */
	@SuppressWarnings("static-access")
	@Override
	public void handleText(char[] data, int pos) {

		String str = new String(data);

		String[] result = str.split("\\W");
		String addingKeyWord = "";
		Keyword keyFilter = new Keyword();

		for (String iter : result) {
			// temp = token.nextToken();
			addingKeyWord = keyFilter.makeKeyword(iter);
			if (!addingKeyWord.equals("")) {
				String currentURL = base.toString();
				if (bigTbl.containsKey(addingKeyWord)) {
					// word already exist in big HashTable
					Hashtable<String, Integer> smallTbl = bigTbl
							.get(addingKeyWord);

					// check if the URL exist in the small hashTable
					if (smallTbl.containsKey(currentURL)) {
						// URL exists add count hits
						smallTbl.put(currentURL, smallTbl.get(currentURL) + 1);

					}
					else {
						// URL not exist in small hashtable, add new one
						smallTbl.put(currentURL, 1);
						wordCount++;
					}
					bigTbl.put(addingKeyWord, smallTbl);
					if (Atag) {
						anchorWords.add(addingKeyWord);
					
					}
				}
				else {
					// word not yet exist in big HashTable, add it
					Hashtable<String, Integer> small = new Hashtable<String, Integer>();
					small.put(currentURL, 1);
					bigTbl.put(addingKeyWord, small);
					wordCount++;
					if (Atag) {
						anchorWords.add(addingKeyWord);
					
					}
				}
				
			}
		}

	}

	/**
	 * 
	 * @return list
	 */
	public LinkedList<String> getHrefList() {
		return hrefList;
	}

	public LinkedList<String> getList2() {
		return anchorWords;
	}

	public Hashtable<String, LinkedList<String>> getHash() {
		return anchorList;
	}

}
